package com.tuanzi.loan.business.service.family.impl;

import com.tuanzi.loan.business.entity.CurrentUser;
import com.tuanzi.loan.business.entity.LoginUser;
import com.tuanzi.loan.business.entity.system.DataPermission;
import com.tuanzi.loan.business.repository.family.FirstPartyPrepaymentRepository;
import com.tuanzi.loan.business.service.family.FirstPartyPrepaymentService;
import com.tuanzi.loan.core.aspect.Debug;
import com.tuanzi.loan.core.vo.PageSearcher;
import com.tuanzi.loan.vo.request.family.BusinessPrepaymentSearchRequest;
import com.tuanzi.loan.vo.request.family.PartnerBalanceSearchRequest;
import com.tuanzi.loan.vo.response.family.BusinessPrepaymentSearchResponse;
import com.tuanzi.loan.vo.response.family.PartnerBalanceSearchResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Objects;

@Debug
@Service
@Transactional
public class FirstPartyPrepaymentServiceImpl implements FirstPartyPrepaymentService {

    @Autowired
    private FirstPartyPrepaymentRepository firstPartyPrepaymentRepository;

    private static final String DATA_PERMISSION_PREFIX = "PARTNER_BALANCE_";

    /**
     * 创建商务充值
     *
     * @param businessPrepayment 模板ID，合作方名，点击单价, 充值金额, 操作人
     * @return 结果
     */
    @Override
    public Integer create(BusinessPrepaymentSearchRequest businessPrepayment) {
        if (Objects.isNull(businessPrepayment))
            throw new NullPointerException("businessPrepayment is null");
        if (Objects.isNull(businessPrepayment.getModelId())
                || Objects.isNull(businessPrepayment.getPartnerName())
                || Objects.isNull(businessPrepayment.getAmountPerClick())
                || Objects.isNull(businessPrepayment.getRechargeBalance())
                || Objects.isNull(businessPrepayment.getOperatorName()))
            throw new IllegalArgumentException("businessPrepayment is invalid");
        return firstPartyPrepaymentRepository.create(businessPrepayment);
    }

    /**
     * 更新山商务充值
     *
     * @param businessPrepayment 模板ID，合作方名，操作人，点击单价
     * @return 结果
     */
    @Override
    public Integer update(BusinessPrepaymentSearchRequest businessPrepayment) {
        if (Objects.isNull(businessPrepayment))
            throw new NullPointerException("businessPrepayment is null");
        if (Objects.isNull(businessPrepayment.getModelId())
                || Objects.isNull(businessPrepayment.getPartnerName())
                || Objects.isNull(businessPrepayment.getAmountPerClick())
                || Objects.isNull(businessPrepayment.getOperatorName()))
            throw new IllegalArgumentException("businessPrepayment is invalid");

        return firstPartyPrepaymentRepository.update(businessPrepayment);
    }

    /**
     * 充值,添加充值记录，更新商务充值的操作人信息
     * 充值金额可为负数,但余额不可为负数
     * 更新活动状态
     *
     * @param businessPrepayment 模板ID，合作方名, 充值金额, 操作人
     * @return 结果
     */
    @Override
    public Integer recharge(BusinessPrepaymentSearchRequest businessPrepayment) {
        if (Objects.isNull(businessPrepayment))
            throw new NullPointerException("businessPrepayment is null");
        if (Objects.isNull(businessPrepayment.getModelId())
                || Objects.isNull(businessPrepayment.getPartnerName())
                || Objects.isNull(businessPrepayment.getRechargeBalance())
                || Objects.isNull(businessPrepayment.getOperatorName()))
            throw new IllegalArgumentException("businessPrepayment is invalid");
        return firstPartyPrepaymentRepository.recharge(businessPrepayment);
    }

    /**
     * 禁用商务充值
     *
     * @param modelId 模板ID
     * @return 结果
     */
    @Override
    public Integer disable(Long modelId) {
        if (Objects.isNull(modelId))
            throw new NullPointerException("modelId is null");
        return firstPartyPrepaymentRepository.changeStatus(modelId, FirstPartyPrepaymentRepository.PrepaymentProductStatus.DISABLE);
    }

    /**
     * 禁用商务充值
     *
     * @param modelId 模板ID
     * @return 结果
     */
    @Override
    public Integer enable(Long modelId) {
        if (Objects.isNull(modelId))
            throw new NullPointerException("modelId is null");
        return firstPartyPrepaymentRepository.changeStatus(modelId, FirstPartyPrepaymentRepository.PrepaymentProductStatus.ENABLE);
    }

    /**
     * 批量禁用商务充值
     *
     * @param modelIds 模板ID列表
     */
    @Override
    public void batchDisable(List<Long> modelIds) {
        if (Objects.isNull(modelIds))
            throw new NullPointerException("modelIds is null");
        for (Long modelId :modelIds){
            Integer result = firstPartyPrepaymentRepository.changeStatus(modelId, FirstPartyPrepaymentRepository.PrepaymentProductStatus.DISABLE);
            if (result == 0)
                throw new RuntimeException("batch disable failed");
        }
    }

    /**
     * 批量启用商务充值
     *
     * @param modelIds 模板ID列表
     */
    @Override
    public void batchEnable(List<Long> modelIds) {
        if (Objects.isNull(modelIds))
            throw new NullPointerException("modelIds is null");
        for (Long modelId : modelIds){
            Integer result = firstPartyPrepaymentRepository.changeStatus(modelId, FirstPartyPrepaymentRepository.PrepaymentProductStatus.ENABLE);
            if (result == 0)
                throw new RuntimeException("batch disable failed");
        }
    }

    /**
     * 获取商务充值余额
     *
     * @param modelId 模板ID
     * @return 充值金额
     */
    @Override
    public Double getPrepaymentBalance(Long modelId) {
        if (Objects.isNull(modelId))
            throw new NullPointerException("modelId is null");
        return firstPartyPrepaymentRepository.getPrepaymentBalance(modelId);
    }

    /**
     * 商务充值查询
     *
     * @param pageSearcher 模板ID，合作方名
     * @return 响应列表
     */
    @Override
    public Page<BusinessPrepaymentSearchResponse> listBusinessPrepayment(PageSearcher<BusinessPrepaymentSearchRequest> pageSearcher) {
        if (Objects.isNull(pageSearcher))
            throw new NullPointerException("pageSearcher is null");
        if (Objects.isNull(pageSearcher.getSearchCondition()) || Objects.isNull(pageSearcher.getPageable()))
            throw new NullPointerException("businessPrepaymentSearchRequest or pageable is null");
        return firstPartyPrepaymentRepository.listBusinessPrepayment(pageSearcher.getSearchCondition(),pageSearcher.getPageable());
    }

    /**
     * 合作方余额查询
     *
     * @param pageSearcher 开始时间，结束时间，模板ID，合作方名
     * @return 响应列表
     */
    @Override
    public Page<PartnerBalanceSearchResponse> listPartnerBalance(PageSearcher<PartnerBalanceSearchRequest> pageSearcher) {
        if (Objects.isNull(pageSearcher))
            throw new NullPointerException("pageSearcher is null");
        if (Objects.isNull(pageSearcher.getSearchCondition()) || Objects.isNull(pageSearcher.getPageable()))
            throw new NullPointerException("partnerBalanceSearchRequest or pageable is null");
        // 判断特定数据权限 目前只允许一个用户对应一个合作方
        LoginUser user = CurrentUser.get();
        if (Objects.nonNull(user)){
            Map<String, DataPermission> dataPermissionMap = user.getDataPermissions();
            if (dataPermissionMap.size() > 0){
                List<Long> modelIds = firstPartyPrepaymentRepository.getAllModelId();
                DataPermission permission = null;
                for (Long modelId : modelIds){
                    permission = dataPermissionMap.get(DATA_PERMISSION_PREFIX + modelId);
                    if (Objects.nonNull(permission)){
                        pageSearcher.getSearchCondition().setModelId(modelId);
                        break;
                    }
                }
            }
        }
        return firstPartyPrepaymentRepository.listPartnerBalance(pageSearcher.getSearchCondition(),pageSearcher.getPageable());
    }
}
